﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LAB.Manager
{
    public static class TagManager
    {

        public delegate void handler(t_tag tag);
        public delegate void searchHandler(List<int> tagIds);

        public static event handler afterInsert;
        public static event handler afterDelete;
        public static event handler afterEdit;
        public static event searchHandler afterSearch;



        // 主要用以绑定事件
        static TagManager()
        {


            // tag的使用频率随着被查询而加了一次
            TagManager.afterSearch += (tagIds) =>
            {
                //using (var db = new TagerEntities())
                //{
                //    tagIds.ForEach(c => addOne(db, c));
                //}
            };
            #region syno 同义词

            // 标签的删除对同义词的影响
            TagManager.afterDelete += (tag) =>
            {
                List<t_syno> synos = SynoManager.getSynosByTagId(tag.id);
                synos.ForEach(c => SynoManager.delete(c.id));
            };
            // 标签的状态被设置为0对同义词的影响
            TagManager.afterEdit += (tag) =>
            {
                if (tag.status == 0)
                {
                    List<t_syno> synos = SynoManager.getSynosByTagId(tag.id);
                    synos.ForEach(c => SynoManager.delete(c.id));
                }
            };
            #endregion

            #region finder 查找器
            //  标签的删除 对finder的影响
            TagManager.afterDelete += (tag) =>
            {
                using (var db = new TagerEntities())
                {
                    var finderTag = db.t_finderTag.FirstOrDefault(ft => ft.tagId == tag.id);
                    if (finderTag != null)
                    {
                        db.t_finderTag.Remove(finderTag);
                        db.SaveChanges();
                    }
                }
            };

            // 标签被冻结,对finder的影响
            TagManager.afterEdit += (tag) =>
            {
                if (tag.status == 0)
                {
                    using (var db = new TagerEntities())
                    {
                        var list = db.t_finderTag.Where(c => c.tagId == tag.id);
                        foreach (var fti in list)
                        {
                            db.t_finderTag.Remove(fti);
                        }
                        db.SaveChanges();

                    }
                }
            };

            #endregion

        }


        public static bool insert(int bagId, string name, string editor)
        {
            var rst = false;
            using (var db = new TagerEntities())
            {
                var bag = db.t_bag.FirstOrDefault(c => c.id == bagId);
                if (bag == null || bag.status == 0)
                {
                    return false;
                }

                // 不可以同名
                if (db.t_tag.Any(c => c.name == name))
                {
                    return false;
                }

                var tag = new t_tag() { bagId = bagId, count = 0, dt = DateTime.Now, editor = editor, name = name, status = 0 };
                db.t_tag.Add(tag);
                db.SaveChanges();
                rst = true;
                // trigger
                if (afterInsert != null)
                {
                    afterInsert(tag);
                }
            }
            return rst;
        }


        public static bool edit(int tagId, int status, string editor)
        {
            var rst = false;


            using (var db = new TagerEntities())
            {
                var tag = db.t_tag.FirstOrDefault(c => c.id == tagId);
                if (tag == null )
                {
                    return false;
                }
                tag.status = status;
                db.SaveChanges();
                rst = true;
                // trigger
                if (afterEdit != null)
                {
                    afterEdit(tag);
                }
            }
            return rst;
        }

        public static bool delete(int tagId, string editor)
        {
            var rst = false;
          

            using (var db = new TagerEntities())
            {
                var tag = db.t_tag.FirstOrDefault(c => c.id == tagId);
                if (tag == null)
                {
                    return false;
                }
                db.t_tag.Remove(tag);
                db.SaveChanges();
                rst = true;
                // trigger
                if (afterDelete != null)
                {
                    afterDelete(tag);
                }
            }

            return rst;

        }


        public static List<t_tag> search(List<int> bagIds, int status, int pageIndex, int pageSize,out int count)
        {
            List<t_tag> rst = null;
            IEnumerable<t_tag> tags = null;
            count = 0;
            using (var db = new TagerEntities())
            {
                tags = db.t_tag;
                if (bagIds != null)
                {
                    tags = tags.Where(c => bagIds.Any(d => d == c.bagId));
                }
                if (status != -1)
                {
                    tags = tags.Where(c => c.status == status);
                }
                count = tags.Count();
                tags = tags.Skip(pageIndex * pageSize).Take(pageSize);
                rst = tags.ToList();
                // trigger
                if (afterSearch != null)
                {
                    afterSearch(tags.Select(c => c.id).ToList());
                }
            }

            return rst;

        }

        public static List<t_tag> search(List<int> bagIds, int status, int pageIndex, int pageSize) {
            var count = 0;
            return search(bagIds, status, pageIndex, pageSize, out count);
        }

        public static List<t_tag> searchByVideoId(int videoId)
        {
            List<t_tag> rst = null;
            IEnumerable<t_tag> tags = null;
            using (var db = new TagerEntities())
            {
                var list = db.t_videoTag.Where(c => c.videoId == videoId);
                var listFormat = db.t_tag.Where(c => list.Any(d => d.tagId == c.id));
                tags = listFormat;
                rst = tags.ToList();

            }

            return rst;
        }

        public static List<int> translate(List<string> tagNames)
        {
            List<int> rst = null;
            return rst;

        }

        static bool addOne(TagerEntities db, int tagId)
        {
            var rst = false;
            var tag = db.t_tag.FirstOrDefault(c => c.id == tagId);
            if (tag == null)
            {
                return false;
            }
            tag.count++;
            db.SaveChanges();
            rst = true;
            return rst;
        }




        public static List<t_tag> getHotTags(int count)
        {
            List<t_tag> rst = null;
            IEnumerable<t_tag> tags = null;
            using (var db = new TagerEntities())
            {
                var bagIds = db.t_bag.Where(c => c.status == 1).Select(c => c.id).ToList();
                tags = db.t_tag.Where(c => bagIds.Count(d => d == c.bagId) > 0 && c.status == 1).OrderBy(c => c.count).Take(count);
                rst = tags.ToList();

                // trigger
                afterSearch(tags.Select(c => c.id).ToList());
            }

            return rst;
        }
    }
}

